package com.zmn.oms.third.zhimi.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.oms.business.interfaces.baidumap.BaiduMapBService;
import com.zmn.oms.business.interfaces.track.OrderTrackBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.baidumap.LngLatLocation;
import com.zmn.oms.model.dto.product.OrderProductDTO;
import com.zmn.oms.model.dto.track.OrderTrackDTO;
import com.zmn.oms.model.dto.track.OrderTrackDetailDTO;
import com.zmn.oms.model.entity.track.OrderTrackQuery;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.track.OrderTrackVO;
import com.zmn.oms.model.vo.work.ZsOrderWorkVO;
import com.zmn.oms.third.base.dto.api.ApiInvokResult;
import com.zmn.oms.third.zhimi.ZhimiApiInvoker;
import com.zmn.oms.third.zhimi.ZhimiConsts;
import com.zmn.oms.third.zhimi.ZhimiMapper;
import com.zmn.oms.third.zhimi.api.ZhimiExpressResp;
import com.zmn.oms.third.zhimi.api.ZhimiOrderResp;
import com.zmn.oms.third.zhimi.entity.CreateOrder4ZhimiDTO;
import com.zmn.oms.third.zhimi.entity.ZhimiConfig;
import com.zmn.oms.third.zhimi.entity.ZhimiOrderExtend;
import com.zmn.oms.third.zhimi.service.ZhimiOrderExtendService;
import com.zmn.oms.third.zhimi.service.ZhimiOrderService;
import com.zmn.oms.zmn.business.interfaces.open.channel.ChannelConfigBService;
import com.zmn.oms.zmn.business.interfaces.proxy.ProxyOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkQueryBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 类描述：
 *
 * @author lhl
 * @date 2020/04/27 16:05
 */
@Slf4j
@Service("zhimiOrderService")
public class ZhimiOrderServiceImpl implements ZhimiOrderService {

    @Autowired
    private ZhimiOrderExtendService zhimiOrderExtendService;
    @Autowired
    private ChannelConfigBService channelConfigBService;
    @Autowired
    private ProxyOrderBService proxyOrderBService;
    @Autowired
    private OrderTrackBService orderTrackBService;
    @Autowired
    private WorkFlowContextBService workFlowContextBService;
    @Autowired
    protected ZsOrderWorkQueryBService zsOrderWorkQueryBService;
    @Autowired
    private BaiduMapBService baiduMapBService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected AreaListRemoteService areaListRemoteService;
//    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
//    protected DocumentaryContentListRemoteService documentaryContentListRemoteService;

    private ZhimiConfig dbConfig;

    @Override
    public void pullOrders() {
        ApiInvokResult<List<ZhimiOrderResp>> result = ZhimiApiInvoker.pullOrders(ZhimiConsts.APP_ID);

        if (!result.isSuccess()) {
            log.error("【{}】 拉取订单失败：{}", ZhimiConsts.CHANNEL_NAME, result.getMsg());
            return;
        }

        List<CreateOrder4ZhimiDTO> zmnOrders = null;

        try {
            zmnOrders = buildZmnOrders(result.getData());
        } catch (Exception e) {
            log.error(String.format("【{}】解析订单数据失败：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
        }

        for (CreateOrder4ZhimiDTO zmnOrder : zmnOrders) {
            try {
                OrderBO order = proxyOrderBService.createOrder(zmnOrder);

                OrderWork orderWork = order.getOrderWork();

                ZhimiOrderExtend model = new ZhimiOrderExtend();
                model.setOrderId(orderWork.getOrderId());
                model.setOuterId(orderWork.getOuterId());
                model.setOriginalServiceType(zmnOrder.getZhimiServiceType());
                model.setServiceType(zmnOrder.getZhimiServiceType());
                model.setAcFlag(zmnOrder.getAcFlag());
                zhimiOrderExtendService.saveZhimiOrderExtend(model);

                if (Objects.equals(GlobalConsts.YES, zmnOrder.getCollectionFee())) {
                    try {
                        autoOrderTrack(orderWork);
                    } catch (Exception e) {
                        log.error(String.format("【%s】保存自动跟单失败exit：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
                        throw new OmsBaseException("保存自动跟单失败："+ e.getMessage());
                    }
                }
            } catch (Exception e) {
                log.error(String.format("【%s】保存订单失败exit：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
            }
        }
    }

    @Override
    public void pullOrderOne(Integer serviceType) throws OmsBaseException {
        ApiInvokResult<List<ZhimiOrderResp>> result = ZhimiApiInvoker.pullOrders(ZhimiConsts.APP_ID);

        if (!result.isSuccess()) {
            log.error("【{}】 拉取订单失败：{}", ZhimiConsts.CHANNEL_NAME, result.getMsg());
            throw new OmsBaseException("拉取订单失败："+ result.getMsg());
        }

        List<CreateOrder4ZhimiDTO> zmnOrders = null;

        try {
            zmnOrders = buildZmnOrders(result.getData());
        } catch (Exception e) {
            log.error(String.format("【%s】解析订单数据失败：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
            throw new OmsBaseException("解析订单数据失败："+ e.getMessage());
        }

        if (!CollectionUtils.isEmpty(zmnOrders)) {
            try {
                CreateOrder4ZhimiDTO zmnOrder = null;
                for (CreateOrder4ZhimiDTO item : zmnOrders) {
                    if (Objects.equals(item.getZhimiServiceType(), serviceType)) {
                        zmnOrder = item;
                        break;
                    }
                }

                if (zmnOrder == null) {
                    throw new OmsBaseException("没有该服务类型的新单信息！");
                }

                OrderBO order = proxyOrderBService.createOrder(zmnOrder);

                OrderWork orderWork = order.getOrderWork();

                ZhimiOrderExtend model = new ZhimiOrderExtend();
                model.setOrderId(orderWork.getOrderId());
                model.setOuterId(orderWork.getOuterId());
                model.setOriginalServiceType(zmnOrder.getZhimiServiceType());
                model.setServiceType(zmnOrder.getZhimiServiceType());
                model.setAcFlag(zmnOrder.getAcFlag());
                zhimiOrderExtendService.saveZhimiOrderExtend(model);

                if (Objects.equals(GlobalConsts.YES, zmnOrder.getCollectionFee())) {
                    try {
                        autoOrderTrack(orderWork);
                    } catch (Exception e) {
                        log.error(String.format("【%s】保存自动跟单失败exit：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
                        throw new OmsBaseException("保存自动跟单失败："+ e.getMessage());
                    }
                }

            } catch (Exception e) {
                log.error(String.format("【%s】保存订单失败exit：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
                throw new OmsBaseException("保存订单失败："+ e.getMessage());
            }


        }
        else {
            throw new OmsBaseException("没有该服务类型的新单信息！");
        }
    }

    @Override
    public void testAddOrderOne(ZhimiOrderResp zhimiOrderResp) {
        List<CreateOrder4ZhimiDTO> zmnOrders = null;

        try {
            zmnOrders = buildZmnOrders(Lists.newArrayList(zhimiOrderResp));
        } catch (Exception e) {
            log.error(String.format("【%s】解析订单数据失败：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
        }

        if (!CollectionUtils.isEmpty(zmnOrders)) {
            try {
                CreateOrder4ZhimiDTO zmnOrder = zmnOrders.get(0);
                OrderBO order = proxyOrderBService.createOrder(zmnOrder);

                OrderWork orderWork = order.getOrderWork();

                ZhimiOrderExtend model = new ZhimiOrderExtend();
                model.setOrderId(orderWork.getOrderId());
                model.setOuterId(orderWork.getOuterId());
                model.setOriginalServiceType(zmnOrder.getZhimiServiceType());
                model.setServiceType(zmnOrder.getZhimiServiceType());
                model.setAcFlag(zmnOrder.getAcFlag());
                model.setWarranty(ZhimiConsts.WARRANTY_IN); // 默认保内
                zhimiOrderExtendService.saveZhimiOrderExtend(model);

                if (Objects.equals(GlobalConsts.YES, zmnOrder.getCollectionFee())) {
                    try {
                        autoOrderTrack(orderWork);
                    } catch (Exception e) {
                        log.error(String.format("【%s】保存自动跟单失败exit：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
                        throw new OmsBaseException("保存自动跟单失败："+ e.getMessage());
                    }
                }
            } catch (Exception e) {
                log.error(String.format("【%s】保存订单失败exit：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
            }
        }
    }

    /**
     * 查询申请的配件是否发货，并获取快递信息
     */
    @Override
    public void pullAppliedPartExpress(Date startTime) {
        List<ZhimiOrderExtend> list = zhimiOrderExtendService.listNoExpressOrders(startTime);

        if (!CollectionUtils.isEmpty(list)) {
            for (ZhimiOrderExtend item : list) {
                zhimiOrderExtendService.pullAppliedPartExpress(item);
            }
        }
    }

    /**
     * 查询指定订单申请的配件是否发货，并获取快递信息
     */
    @Override
    public ApiInvokResult pullAppliedPartExpressByOrderId(Long orderId) {
        ZhimiOrderExtend zhimiOrderExtend = zhimiOrderExtendService.findZhimiOrderExtend(orderId, false);
        if (zhimiOrderExtend == null) {
            return ApiInvokResult.fail("订单不存在！");
        }

        ZhimiExpressResp zhimiExpressResp = zhimiOrderExtendService.pullAppliedPartExpress(zhimiOrderExtend);

        if (zhimiExpressResp == null) {
            return ApiInvokResult.fail("查询失败！");
        }

        ApiInvokResult result = new ApiInvokResult();
        result.setSuccess(true);
        result.setMsg(JSON.toJSONString(zhimiExpressResp));
        return result;
    }
    /**
     * 构造啄木鸟保存工单对象
     * @param orders
     * @return
     */
    private List<CreateOrder4ZhimiDTO> buildZmnOrders(List<ZhimiOrderResp> orders) throws OmsBaseException {
        List<CreateOrder4ZhimiDTO> zmnOrderList = new LinkedList<>();

        if (CollectionUtils.isEmpty(orders)) {
            return zmnOrderList;
        }

        for (ZhimiOrderResp item : orders) {
            String outerId = item.getServicenumber();

            // 校验是不是重复的订单消息
            ZsOrderWorkVO orderWork = zsOrderWorkQueryBService.findOrderWorkByOuterId(outerId, ZhimiConsts.CHANNEL_ID);
            if (orderWork != null) {
                log.info("【{}】重复的消息数据（已忽略） OuterId:[{}]", ZhimiConsts.CHANNEL_NAME, outerId);
                continue;
            }

            CreateOrder4ZhimiDTO createOrderDTO = new CreateOrder4ZhimiDTO();

            createOrderDTO.setOuterData(item.getMetadata());
            createOrderDTO.setChannelId(ZhimiConsts.CHANNEL_ID);

            createOrderDTO.setOuterId(outerId);
            createOrderDTO.setContactName(item.getAccount());
            createOrderDTO.setTelephone(item.getTelephone());
            createOrderDTO.setRemark(item.getServicedescription());

            // 是否需要代收货款
            boolean isCollectionFee = Objects.equals(1, item.getIscollection());
            createOrderDTO.setCollectionFee(isCollectionFee ? GlobalConsts.YES : GlobalConsts.NO);
            if (isCollectionFee) {
                String remark = createOrderDTO.getRemark();
                String isCollectionRemark = "该单需要服务商代收货款，代收金额为90元";
                if (StringUtils.isNotBlank(remark)) {
                    createOrderDTO.setRemark(String.format("%s，%s", isCollectionRemark, remark));
                }
                else {
                    createOrderDTO.setRemark(isCollectionRemark);
                }
            }

            // Appointmenttime 预约时间，格式：yyyy-MM-dd HH:mm:ss，
            String dutytimeStr = item.getAppointmenttime();
            if (StringUtils.isNotBlank(dutytimeStr)) {
                Date dutyTime = DateUtil.parse(dutytimeStr, DateUtil.FORMAT_DEFAULT);
                // 忽略掉当前时间超过预约时间的情况，由线下去确定预约时间
                if (dutyTime.getTime() > System.currentTimeMillis()) {
                    createOrderDTO.setDutyTime(DateUtil.round(dutyTime, DateUtil.UNIT_MINUTE));
                }
            }

            try {
                // 地址转换
                _fillAddress(createOrderDTO, item);
                // 商品转换
                _fillProductInfo(createOrderDTO, item);


            } catch (Exception e) {
                log.error(e.getMessage(), e);
                throw new OmsBaseException("产品/地址信息有误！");
            }

            // 智米订单为厂商保内单，由言而有信平台服务
            createOrderDTO.setFactory(GlobalConsts.YES);
            createOrderDTO.setBizType(GlobalConsts.BIZ_TYPE_F);
            createOrderDTO.setGender(GlobalDict.GENDER_NO);
            zmnOrderList.add(createOrderDTO);
        }

        return zmnOrderList;

    }

    /**
     * 补全产品信息
     * @param zmnOrder
     * @param zhimiOrder
     */
    private void _fillProductInfo(CreateOrder4ZhimiDTO zmnOrder, ZhimiOrderResp zhimiOrder) {
        // 默认产品是马桶
        String zhimiProductName = zhimiOrder.getFirstmodel();
        Integer serviceType = zhimiOrder.getServicetype();

        if (!ZhimiConsts.isServiceTypeUseable(serviceType)) {
            serviceType = ZhimiConsts.SERVICE_TYPE_REPAIR;

            String logStr = String.format("无法识别该服务类型 serviceType:[%s]，使用默认服务类型：[%d]",
                    String.valueOf(serviceType), serviceType);

            zmnOrder.setRemark(String.format("%s；%s", zmnOrder.getRemark(), logStr));

            log.info("【{}】{}", ZhimiConsts.CHANNEL_NAME, logStr);
        }

        OrderProductDTO orderProduct = new OrderProductDTO();
        orderProduct.setProductId(ZhimiMapper.getProductId(zhimiProductName, serviceType));
        orderProduct.setNumber(1);
        zmnOrder.setOrderProductList(Lists.newArrayList(orderProduct));
        // 厂商产品写死：智能马桶盖
        zmnOrder.setFacProductId("12041");

        // 是否是空调订单
        zmnOrder.setAcFlag(ZhimiMapper.isAC(zhimiProductName) ? GlobalConsts.YES : GlobalConsts.NO);
        zmnOrder.setZhimiServiceType(serviceType);
    }

    /**
     * 补全订单地址
     * @param orderDTO
     * @param zhimiOrder
     */
    private void _fillAddress(CreateOrder4ZhimiDTO orderDTO, ZhimiOrderResp zhimiOrder) {
        String province = Optional.ofNullable(zhimiOrder.getProvince()).orElse("");
        String city = Optional.ofNullable(zhimiOrder.getCity()).orElse("");
        String county = Optional.ofNullable(zhimiOrder.getCounty()).orElse("");
        String street = Optional.ofNullable(zhimiOrder.getStreet()).orElse("");
        String address = Optional.ofNullable(zhimiOrder.getAddress()).orElse("");

        orderDTO.setStreet(street); // street字段在数据库中不能为空
        orderDTO.setAddress(address);

        // 去掉空格和括号
        Pattern pattern = Pattern.compile("\\s+|（.*）|[(](.*)[)]");
        Matcher matcher = pattern.matcher(province + city + county + street + address);
        String addressStr = matcher.replaceAll("");

        LngLatLocation location = baiduMapBService.location(addressStr);
        if (location != null) {
            Double lng = Double.valueOf(location.getLng());
            Double lat = Double.valueOf(location.getLat());

            try {
                log.info("Dubbo-获取城市信息-Request：lng=[{}], lat=[{}]", location.getLng(), location.getLat());
                ResponseDTO<com.zmn.base.common.data.common.dro.area.AreaDRO> areaResponse = areaListRemoteService.getAreaByLatAndLng(lng, lat);
                AreaDRO areaDRO = areaResponse.getData();
                log.info("Dubbo-获取城市信息-Response：AreaDRO=[{}]", JSON.toJSONString(areaDRO));
                if (areaDRO != null) {
                    orderDTO.setCityId(areaDRO.getParentId());

                    orderDTO.setLatitude(lat);
                    orderDTO.setLongitude(lng);
                }
            } catch (Exception e) {
                log.error("【{}】使用经纬度获取CityId失败:[{}], lng=[{}], lat=[{}]", ZhimiConsts.CHANNEL_NAME,
                        e.getMessage(), location.getLng(), location.getLat());
            }
        }
        else {
            log.info("获取经纬度失败：address=[{}]", addressStr);
        }

        // 城市解析失败，将城市设置为重庆
        if (orderDTO.getCityId() == null) {
            orderDTO.setCityId(500100);
        }
    }

    /**
     * 查询指定时间录入的订单信息
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public List<ZhimiOrderExtend> listOrdersByCreateTime(Date startTime, Date endTime) {
        return zhimiOrderExtendService.listOrdersByCreateTime(startTime, endTime);
    }

    /**
     * 自动跟单：服务商代收货款
     * @param orderWork
     * @throws Exception
     */
    private void autoOrderTrack(OrderWork orderWork) {
        Integer orderTractTypeId = OrderConsts.ORDER_TRACT_ZHIMI_TYPE_ID;

        ZhimiConfig zhimiConfig = getZhimiConfig();
        if (zhimiConfig != null && zhimiConfig.getOrderTrackTypeId() != null) {
            orderTractTypeId = zhimiConfig.getOrderTrackTypeId();
        }

        //查询是否已设置跟单
        OrderTrackQuery query = new OrderTrackQuery();
        query.setOrderId(orderWork.getOrderId());
        query.setWorkId(orderWork.getWorkId());
        query.setMapId(orderTractTypeId);
        query.setComplete(GlobalConsts.NO);
        Integer orderTrackCount = orderTrackBService.countByQuery(query);
        log.info("#api#orderTrackCount 查询1077跟单是否完成：【{}】", JSON.toJSONString(orderTrackCount));
        //有进行中的跟单则不创建跟单
        if (orderTrackCount != null && orderTrackCount > 0) {
            return;
        }

        //查询指定的跟单信息
        /*List<OrderTrackVO> trackTypeList = Lists.newArrayList();
        DocumentaryContentDIO documentaryContentDIO = new DocumentaryContentDIO();
        documentaryContentDIO.setBizType(orderWork.getBizType());
        documentaryContentDIO.setStatus(GlobalConsts.YES);
        documentaryContentDIO.setId(orderTractTypeId);
        log.info("#api#track 查询跟单项目入参：【{}】", JSON.toJSONString(documentaryContentDIO));
        com.zmn.common.dto2.ResponseDTO<List<DocumentaryContentDRO>>
                responseDTO = documentaryContentListRemoteService.listByQuery(documentaryContentDIO);
        log.info("#api#track 查询跟单项目出参：【{}】", JSON.toJSONString(responseDTO));
        boolean isSuccess = responseDTO.isSuccess();
        if (isSuccess && !org.apache.commons.collections4.CollectionUtils.isEmpty(responseDTO.getData())) {
            responseDTO.getData().forEach(e -> {
                //默认跟单等级为一级
                OrderTrackVO orderTrackVO = OrderTrackVO.builder()
                        .mapId(e.getId())
                        .mapName(e.getContent())
                        .level(OrderConsts.ORDER_TRACT_OTHER_TYPE_LEVEL)
                        .build();
                trackTypeList.add(orderTrackVO);
            });
        }

        if (org.apache.commons.collections4.CollectionUtils.isEmpty(trackTypeList)) {
            log.info("#api#trackTypeList 查询跟单项为空，不处理--------");
            return;
        }

        //保存跟单信息
        OrderTrackDTO orderTrackDTO = new OrderTrackDTO();
        orderTrackDTO.setComplete(GlobalConsts.NO);
        orderTrackDTO.setOrderId(orderWork.getOrderId());
        orderTrackDTO.setWorkId(orderWork.getWorkId());
        orderTrackDTO.setOperator("系统");
        orderTrackDTO.setOperatorId((long) ZhimiConsts.CHANNEL_ID );
        orderTrackDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SYSTEM);

        List<OrderTrackDetailDTO> detailDTOList = new ArrayList<>(trackTypeList.size());
        orderTrackDTO.setDetailDTOList(detailDTOList);

        trackTypeList.forEach(workTrackDTO -> {
            OrderTrackDetailDTO orderTrackDetailDTO = new OrderTrackDetailDTO();
            orderTrackDetailDTO.setMapId(workTrackDTO.getMapId());
            orderTrackDetailDTO.setMapName(workTrackDTO.getMapName());
            orderTrackDetailDTO.setRemark(workTrackDTO.getRemark());
            orderTrackDetailDTO.setLevel(workTrackDTO.getLevel());
            detailDTOList.add(orderTrackDetailDTO);
        });
        //保存
        orderTrackBService.updateTrack(orderTrackDTO);*/
    }

    private ZhimiConfig getZhimiConfig() {
        if (dbConfig == null) {
            synchronized (this) {
                if (dbConfig == null) {
                    dbConfig = channelConfigBService.getConfig(ZhimiConsts.CHANNEL_ID, ZhimiConfig.class);
                }
            }
        }

        return dbConfig;
    }
}
